using System;
using System.ComponentModel;

namespace TuxedoLib
{
	public class TuxedoApp
	{
		private string windowTitle;
		private int screenWidth;
		private int screenHeight;

		public TuxedoApp(string windowTitle, int screenWidth, int screenHeight, bool bypassVerifier)
		{
			if (!bypassVerifier)
			{
				throw new NotImplementedException("Tuxedo Verifier not done yet.");
			}

			BackgroundWorker bg = new BackgroundWorker();

			this.windowTitle = windowTitle ?? "Tuxedo Window";
			this.screenWidth = screenWidth;
			this.screenHeight = screenHeight;
		}

		public event StartLoadEventHandler StartLoad;
		public event PostInitEventHandler PostInit;
		public event UpdateEventHandler Update;
		public event RenderEventHandler Render;

		public void StartPipeline(int targetFps)
		{
			this.StartLoad(this, new EventArgs());
			this.PostInit(this, new EventArgs());

			GameWindow window = new GameWindow(this.screenWidth, this.screenHeight, this.windowTitle, targetFps, this);
			window.ShowDialog();
		}

		internal void DoUpdate(Event[] events, PressedKeysLookup pressedKeys)
		{
			if (events.Length != 0)
			{

			}
			this.Update(this, new UpdateEventArgs(events, pressedKeys));
		}

		internal void DoRender(Image screen)
		{
			this.Render(this, new RenderEventArgs(screen));
		}
	}

	public delegate void StartLoadEventHandler(object sender, EventArgs e);
	public delegate void PostInitEventHandler(object sender, EventArgs e);
	public delegate void UpdateEventHandler(object sender, UpdateEventArgs e);
	public delegate void RenderEventHandler(object sender, RenderEventArgs e);

	public class RenderEventArgs
	{
		private TuxedoLib.Image screen;

		internal RenderEventArgs(TuxedoLib.Image screen)
		{
			this.screen = screen;
		}

		public Image Screen { get { return this.screen; } }
	}

	public class UpdateEventArgs
	{
		// TODO: replace these with umodifiable collections
		private Event[] events;
		private PressedKeysLookup pressedKeys;

		internal UpdateEventArgs(Event[] events, PressedKeysLookup pressedKeys)
		{
			this.events = events;
			this.pressedKeys = pressedKeys;
		}

		public Event[] Events { get { return this.events; } }
		public PressedKeysLookup PressedKeys { get { return this.pressedKeys; } }
	}
}